home *** CD-ROM | disk | FTP | other *** search
- ; ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; This is a 3D animation demo, written by Yann/Iguana
- ; Credits to:
- ; * Jare/Iguana for his nonjump Bresenham,
- ; * Tran/Renaissance for letting us see the sources of the Amnesia demo
- ; * Tran/Renaissance for his great PMODE 2.4
- ;
- ; ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- ; History: 0th version: '93
- ; p0th version: june 30'94 (pmode version)
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Macros to profile the 3D engine
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- SetBorder2 MACRO Color
- push ax
- push dx
- cli ; So that the flip-flop isn't
- ; uninit-ed by some IRQ...
- mov dx,3DAh
- in al,dx ; Init the flip-flop for the
- ; attribute controller
- mov dx,3C0h ; Attribute controller port
- mov al,31h ; Overscan reg, don't switch ray off
- out dx,al ; Write Register #
- mov al,Color
- out dx,al ; Write Border Color
- sti
- pop dx
- pop ax
- ENDM
-
- SetBorder MACRO Color ; To profile
- ;SetBorder2 Color
- ENDM
-
- .386p
- code32 segment para public use32
- assume cs:code32, ds:code32
-
- include pmode.inc
-
- public _main
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; DATA
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
-
- ClippedFacetsBuffer DW 4096 DUP (?)
- ; For each facet: DW facet type
- ; DW data1 (1st byte color for solid facets)
- ; DW data2
- ; DW # of points in the facet
- ; DW n DUP (x,y,z)
- SortedFacetsList DW 4096 DUP (?)
- ; For each facet: DD offset of the next linkedlist item
- ; DD distance of the middle point ^ 2
- ; DD offset of the facet (in the Clip. buffer)
- SortedFacetsHeadPtr DD ?
- NextFreeSlotPtr DD ?
-
- LinesBuffer1 DW 3072 DUP (?)
- LinesBuffer2 DW 3072 DUP (?)
- LinesBufferPtr DD ?
- NumBufferedLines1 DW ?
- NumBufferedLines2 DW ?
- NumBufferedLinesPtr DD ?
-
- EVEN
- QuitPrg DW 0
- VGASeg DW 0A400h
- ; Drawing mode:
- WIREFRAME = 0
- SOLID = 1
- Mode DW SOLID
-
- ; ------------------------ Description of the environment ---------------------
- INCLUDE ..\road.inc
- ; ^^^^^^^^^^^^^^^^^^^^^^^^ Description of the environment ^^^^^^^^^^^^^^^^^^^^^
-
- ; ------------------------ Description of the movement ------------------------
- Movement LABEL WORD
-
- INCLUDE ..\roadm.inc
-
- DW -1
-
- ; ^^^^^^^^^^^^^^^^^^^^^^^^ Description of the movement ^^^^^^^^^^^^^^^^^^^^^^^^
-
- CameraPts LABEL WORD
- DW NUM_POINTS DUP (?,?,?)
-
- NumFacets DW ?
-
- ;SinTable created by Jon Beltran de Heredia
- ;Sines are in 8.8 fixedpoint, from 0 degrees to 360+90 degrees (in order to
- ; calculate the cosines with the same table)
- SinTbl LABEL WORD
- DW 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
- DW 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
- DW 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
- DW 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
- DW 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
- DW 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256
- DW 256,256,256,256,255,255,255,254,254,253,252,251,250,249,248
- DW 247,246,245,243,242,241,239,237,236,234,232,230,228,226,224
- DW 222,219,217,215,212,210,207,204,202,199,196,193,190,187,184
- DW 181,178,175,171,168,165,161,158,154,150,147,143,139,136,132
- DW 128,124,120,116,112,108,104,100,96,92,88,83,79,75,71
- DW 66,62,58,53,49,44,40,36,31,27,22,18,13,9,4
- DW 0,-4,-9,-13,-18,-22,-27,-31,-36,-40,-44,-49,-53,-58,-62
- DW -66,-71,-75,-79,-83,-88,-92,-96,-100,-104,-108,-112,-116,-120,-124
- DW -128,-132,-136,-139,-143,-147,-150,-154,-158,-161,-165,-168,-171,-175,-178
- DW -181,-184,-187,-190,-193,-196,-199,-202,-204,-207,-210,-212,-215,-217,-219
- DW -222,-224,-226,-228,-230,-232,-234,-236,-237,-239,-241,-242,-243,-245,-246
- DW -247,-248,-249,-250,-251,-252,-253,-254,-254,-255,-255,-255,-256,-256,-256
- DW -256,-256,-256,-256,-255,-255,-255,-254,-254,-253,-252,-251,-250,-249,-248
- DW -247,-246,-245,-243,-242,-241,-239,-237,-236,-234,-232,-230,-228,-226,-224
- DW -222,-219,-217,-215,-212,-210,-207,-204,-202,-199,-196,-193,-190,-187,-184
- DW -181,-178,-175,-171,-168,-165,-161,-158,-154,-150,-147,-143,-139,-136,-132
- DW -128,-124,-120,-116,-112,-108,-104,-100,-96,-92,-88,-83,-79,-75,-71
- DW -66,-62,-58,-53,-49,-44,-40,-36,-31,-27,-22,-18,-13,-9,-4
- DW 0,4,9,13,18,22,27,31,36,40,44,49,53,58,62
- DW 66,71,75,79,83,88,92,96,100,104,108,112,116,120,124
- DW 128,132,136,139,143,147,150,154,158,161,165,168,171,175,178
- DW 181,184,187,190,193,196,199,202,204,207,210,212,215,217,219
- DW 222,224,226,228,230,232,234,236,237,239,241,242,243,245,246
- DW 247,248,249,250,251,252,253,254,254,255,255,255,256,256,256,256
-
-
- ByeMsg DB 'Greetings to everyone in FidoNet.R34 PROASM_E & R34.DEMOS chats'
- DB 0Dh,0Ah
- DB 'Good bye!', 0Dh, 0Ah
- DB 'Coded by Yann/Iguana', 0Dh, 0Ah
- DB '$'
-
- EVEN
- ;*****
- ; Distance: near z clipping plane
- ZN DW ?
- ;*****
- ; Angle: field of view (in degrees)
- FOV DW ?
- ;*****
- ; Distance: from the eye to the projection plane (calc as 100/sin(FOV/2))
- Dist DW ?
- ;*****
- ; Vector: eye coors
- _ex DW ?
- _ey DW ?
- _ez DW ?
- ; Vector: look-at point coors
- _ax DW ?
- _ay DW ?
- _az DW ?
- ; Vector: looking direction
- _tx DW ?
- _ty DW ?
- _tz DW ?
- ; Vector length: |t|
- _t DW ?
- ; Distance: lambda = sqrt(tx^2+ty^2)
- lambda DW ?
- ; 3x3 Matrix: rotation matrix to put t along z axis
- M11 DW ?
- M12 DW ?
- M13 DW ?
- M21 DW ?
- M22 DW ?
- M23 DW ?
- M31 DW ?
- M32 DW ?
- M33 DW ?
-
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
- ; CODE
- ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to calc M matrix from _e and _a vectors
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- CalcM PROC
- ; Assure there is no overflow
- mov ax,[_ax]
- cmp ax,[_ex]
- jne CML0
- mov ax,[_ay]
- cmp ax,[_ey]
- jne CML0
- add ax,256
- mov [_ay],ax
- CML0:
- ; Calc _t = _a - _e
- mov ax,[_ax]
- sub ax,[_ex]
- mov [_tx],ax
- mov bx,[_ay]
- sub bx,[_ey]
- mov [_ty],bx
- mov cx,[_az]
- sub cx,[_ez]
- mov [_tz],cx
- ; Calc lamdba and |t|
- imul ax
- mov di,dx
- mov si,ax
- mov ax,bx
- imul bx
- add si,ax
- adc di,dx
- push di
- push si
- push cx
- call SqRoot
- mov [lambda],ax
- pop ax ; Restore tz
- pop si ; Restore lambda
- pop di ; ^
- imul ax
- add si,ax
- adc di,dx
- call SqRoot
- mov [_t],ax
- ; We got all the needed quantities, calc M1i
- mov cx,[lambda]
- mov ax,[_ty]
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv cx
- mov [M11],ax
- mov ax,[_tx]
- neg ax
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv cx
- mov [M12],ax
- mov [M13],0
- ; Now we calc M2i
- mov bx,[_tz]
- mov si,[lambda]
- mov di,[_t]
- ; Calc M21 = tx*tz/(lambda*|t|)
- mov ax,[_tx]
- imul bx
- idiv si
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M21],ax
- ; Calc M22 = ty*tz/(lambda*|t|)
- mov ax,[_ty]
- imul bx
- idiv si
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M22],ax
- ; Calc M23 = -lambda/|t|
- mov ax,si
- neg ax
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M23],ax
- ; Now we only have to calc M3i = _t normalized
- ; _tz is in BX and |t| is in DI
- mov ax,[_tx]
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M31],ax
- mov ax,[_ty]
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M32],ax
- mov ax,bx ; _tz
- cwd
- mov dl,ah
- mov ah,al
- xor al,al
- idiv di
- mov [M33],ax
- ret
- CalcM ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to calc projection plane distance from the FOV [100/sin(FOV/2)]
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- CalcDist PROC
- movzx ebx,[FOV]
- and bl,0FEh
- mov bx,SinTbl[ebx]
- mov ax,100*256 ; Height o'the screen (scaled)
- xor dx,dx
- div bx
- mov [Dist],ax
- ret
- CalcDist ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to calc 16 bit square root of 32 bit number in DI·SI, ret in AX
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- SqRoot PROC
- xor dx,dx
- mov ax,1
- xor bx,bx
- mov cx,2
- SRML:
- REPT 32
- sub si,ax
- sbb di,dx
- jc SRExit
- add ax,cx ; Add 2
- adc dx,bx ; Add 0
- ENDM
- jmp SRML
- SRExit: clc
- rcr dx,1
- rcr ax,1
- ret
- SqRoot ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to calc the points from the camera's reference frame
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- WToCam PROC
- mov esi,OFFSET WorldPts
- mov edi,OFFSET CameraPts
- mov cx,NUM_POINTS
- WCML: ; Calc X coor
- mov ax,[esi] ; Get X coor
- sub ax,[_ex]
- cwd
- imul [M11]
- mov bx,ax
- mov bp,dx
- mov ax,[esi+2] ; Get Y coor
- sub ax,[_ey]
- cwd
- imul [M12]
- add bx,ax
- adc bp,dx
- mov ax,[esi+4] ; Get Z coor
- sub ax,[_ez]
- cwd
- imul [M13]
- add ax,bx
- adc dx,bp
- mov al,ah
- mov ah,dl
- stosw ; Store X coor tran-ed and rot-ed
- ; Calc Y coor
- mov ax,[esi] ; Get X coor
- sub ax,[_ex]
- cwd
- imul [M21]
- mov bx,ax
- mov bp,dx
- mov ax,[esi+2] ; Get Y coor
- sub ax,[_ey]
- cwd
- imul [M22]
- add bx,ax
- adc bp,dx
- mov ax,[esi+4] ; Get Z coor
- sub ax,[_ez]
- cwd
- imul [M23]
- add ax,bx
- adc dx,bp
- mov al,ah
- mov ah,dl
- stosw ; Store Y coor tran-ed and rot-ed
- ; Calc Z coor
- mov ax,[esi] ; Get X coor
- sub ax,[_ex]
- cwd
- imul [M31]
- mov bx,ax
- mov bp,dx
- mov ax,[esi+2] ; Get Y coor
- sub ax,[_ey]
- cwd
- imul [M32]
- add bx,ax
- adc bp,dx
- mov ax,[esi+4] ; Get Z coor
- sub ax,[_ez]
- cwd
- imul [M33]
- add ax,bx
- adc dx,bp
- mov al,ah
- mov ah,dl
- stosw ; Store Z coor tran-ed and rot-ed
- add esi,6 ; Next point
- dec cx
- jz WCExit ; Loop for all world points
- jmp WCML
- WCExit: ret
- WToCam ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Line drawing routine based upon code by Jare/Iguana (AKA Javier Arévalo)
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Input: AH is the color, coors are in the following vars
- EVEN
- MulBy80 LABEL DWORD
- I = 0
- REPT 200
- DD I*80
- I = I + 1
- ENDM
- X1 DW ?
- X2 DW ?
- Y1 DW ?
- Y2 DW ?
- LVar1 DD 0 ; Increment for DI when there is overflow
- DD 0 ; Inc. for DI when there isn't overflow
- AdjDown DD ? ; Lookup Bresenham's algorithm
- DD 0 ; There isn't AdjDown w/o overflow
- RotBits DB ?,? ; Bits to rot when overflow
- DB ?,? ; Bits to rot when not overflow
-
- LineJmpTblPtr DD ?
-
- EVEN
- DrawLine PROC
- mov BYTE PTR [ColorByte],ah
- mov dx,3C4h
- mov al,2
- out dx,al ; Writes to map mask register
- push ebp
- push ecx
- push esi
- push edi
- movzx eax,[Y1]
- movzx ebx,[Y2]
- movzx ecx,[X1]
- movzx esi,[X2]
- cmp eax,ebx
- jc LL1
- xchg ecx,esi
- xchg eax,ebx
- LL1:
- ; (ecx,eax) = upper point (X1,Y1)
- ; (esi,ebx) = the other one (X2,Y2)
- sub ebx,eax ; deltaY
- movzx edi,[VGASeg]
- shl edi,4
- mov edx,eax
- shl edx,2
- add edi,MulBy80[edx]
- sub edi,_code32a
- mov edx,ecx
- shr edx,2
- add edi,edx
- mov edx,ecx
- and cl,11b
- mov al,00010001b
- rol al,cl
- mov BYTE PTR [MaskByte],al
- sub esi,edx ; deltaX
- jnc LL2
- ; arrives here if going from right to left
- neg esi
- mov [LineJmpTblPtr],OFFSET LineJmpTbl1
- jmp LL2B
-
- LL2: ; arrives here if going from left to right
- mov [LineJmpTblPtr],OFFSET LineJmpTbl2
- ;jmp LL2B
-
- LL2B: cmp esi,ebx ; cmp deltaX,deltaY
- jnc LL3
- ; so deltaX < deltaY => non-overflow: dont rot; overflow: rot 1
- mov [RotBits],1
- mov [RotBits+2],0
- mov edx,esi
- xor esi,esi ; Minor inc.
- mov eax,80 ; Major inc.
- jmp LL4
- LL3: ; so deltaX > deltaY => always rotate
- mov [RotBits],1
- mov [RotBits+2],1
- mov edx,ebx
- mov ebx,esi
- mov esi,80 ; Minor inc.
- xor eax,eax ; Major inc.
- LL4: mov ecx,ebx
- or ecx,ecx
- jz LExit
- ;LL5: ; Now: EAX == Major displacement (every pixel does this).
- ; ESI == Minor (only done when decimal part overflows).
- cmp [LineJmpTblPtr],OFFSET LineJmpTbl1
- jnz DontNeg
- neg eax
- neg esi
- DontNeg:
- add esi,eax
- mov [LVar1],esi
- mov [LVar1+4],eax
- mov esi,edx
- ; Now: eax == nothing
- ; ebx == major axis width
- ; ecx == major axis width
- ; esi == minor axis width
- ; edi == ScreenPtr
- ; ebp == nothing
- mov ebp,ebx
- neg ebp ; ebp == -major axis width (to round)
- mov eax,ebp ; eax == -major a.w.
- add eax,eax ; eax *= 2
- mov [AdjDown],eax
- add esi,esi ; esi == 2*minor a. w. (AdjUp)
- inc ecx ; To draw all the pixels
- mov ebx,ecx
- mov eax,ecx
- add eax,0Fh
- shr eax,4
- mov ecx,eax ; ecx = # of complete 16 pel groups + 1
- mov ch,cl ; Counter will be CH
- and ebx,00001111b ; cx = # of ungrouped pixels
- shl ebx,2
- mov dx,3C5h ; Writes to map mask register
- mov ah,0FFh
- ColorByte = $-1
- mov al,0FFh
- MaskByte = $-1
- add ebx,[LineJmpTblPtr]
- jmp DWORD PTR [ebx]
-
- LineDumpPixel1 MACRO p
- LineLoop1&p:
- out dx,al ; Set map mask register
- mov BYTE PTR [edi],ah
- add ebp,esi
- sbb ebx,ebx
- add ebx,ebx
- mov cl,RotBits[ebx+2]
- add ebx,ebx
- clc
- ror al,cl
- sbb edi,LVar1[ebx+4]
- add ebp,AdjDown[ebx+4]
- ENDM
-
- LineDumpPixel2 MACRO p
- LineLoop2&p:
- out dx,al ; Set map mask register
- mov BYTE PTR [edi],ah
- add ebp,esi
- sbb ebx,ebx
- add ebx,ebx
- mov cl,RotBits[ebx+2]
- add ebx,ebx
- clc
- rol al,cl
- adc edi,LVar1[ebx+4]
- add ebp,AdjDown[ebx+4]
- ENDM
-
- LineLoop1:
- I = 0
- REPT 16
- LineDumpPixel1 %I
- I = I + 1
- ENDM
- EndLineLoop1:
- dec ch
- jnz LineLoop1
- jmp LExit
-
- LineLoop2:
- I = 0
- REPT 16
- LineDumpPixel2 %I
- I = I + 1
- ENDM
- EndLineLoop2:
- dec ch
- jnz LineLoop2
- ;jmp LExit
-
-
- LExit: pop edi
- pop esi
- pop ecx
- pop ebp
- ret
- DrawLine ENDP
-
- EVEN
- LineJmpTbl1 LABEL WORD
- LineDumpLabel1 MACRO p
- DD OFFSET LineLoop1&p
- ENDM
- DD LineLoop10
- I = 15
- REPT 15
- LineDumpLabel1 %I
- I = I - 1
- ENDM
-
- LineJmpTbl2 LABEL WORD
- LineDumpLabel2 MACRO p
- DD OFFSET LineLoop2&p
- ENDM
- DD LineLoop20
- I = 15
- REPT 15
- LineDumpLabel2 %I
- I = I - 1
- ENDM
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to erase all the lines of the previous frame
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- EraseBufferedLines PROC
- mov esi,[NumBufferedLinesPtr]
- mov cx,[esi]
- or cx,cx
- jz EBLExit
- mov esi,[LinesBufferPtr]
- EBLML: push cx
- mov ax,[esi]
- mov [X1],ax
- mov ax,[esi+2]
- mov [Y1],ax
- mov ax,[esi+4]
- mov [X2],ax
- mov ax,[esi+6]
- mov [Y2],ax
- xor ah,ah
- push esi
- call DrawLine
- pop esi
- add esi,8
- pop cx
- dec cx
- jnz EBLMl
- mov esi,[NumBufferedLinesPtr]
- mov WORD PTR [esi],0
- EBLExit:
- ret
- EraseBufferedLines ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to erase all the polygons of the previous frame
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- EraseBufferedPolys PROC
- xor al,al ; Erase with black!
- mov esi,[LinesBufferPtr]
- call DumpPBuf
- mov edi,[LinesBufferPtr]
- call ClearPBuf
- ret
-
- EraseBufferedPolys ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to draw the things in wireframe
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- DWX DW ?
- DWY DW ?
- DWZ DW ?
- DWClr DB ?
-
- EVEN
- DrawWire PROC
- mov esi,[SortedFacetsHeadPtr]
- or esi,esi
- jz _ret
- DWML0: push esi
- mov esi,[esi+8] ; Get effective facet data ptr
- mov cx,[esi+6] ; Get # of points
- dec cx ; Loop for # of pts - 1
- mov al,BYTE PTR [esi+2] ; Get color
- mov [DWClr],al
- add esi,8 ; Skip facet header
- mov ax,[esi]
- mov [DWX],ax
- push ax
- mov ax,[esi+2]
- mov [DWY],ax
- push ax
- mov ax,[esi+4]
- mov [DWZ],ax
- push ax
- add esi,6 ; Skip 1st pt
- DWML1: mov ax,[DWX] ; Don't load again
- mov [L3DX1],ax
- mov ax,[DWY]
- mov [L3DY1],ax
- mov ax,[DWZ]
- mov [L3DZ1],ax
- mov ax,[esi]
- mov [L3DX2],ax
- mov [DWX],ax
- mov ax,[esi+2]
- mov [L3DY2],ax
- mov [DWY],ax
- mov ax,[esi+4]
- mov [L3DZ2],ax
- mov [DWZ],ax
- mov ah,[DWClr]
- push esi
- push cx
- call Draw3DLine
- pop cx
- pop esi
- add esi,6 ; Skip point
- dec cx
- jnz DWML1
- ; Now, we gotta draw the last line
- pop [L3DZ2]
- pop [L3DY2]
- pop [L3DX2]
- mov ax,[DWX]
- mov [L3DX1],ax
- mov ax,[DWY]
- mov [L3DY1],ax
- mov ax,[DWZ]
- mov [L3DZ1],ax
- mov ah,[DWClr]
- call Draw3DLine
- pop esi ; Restore ptr to the linked list
- mov esi,[esi]
- or esi,esi
- jnz DWML0
- ret
- DrawWire ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to draw the things solid!
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- DSOPBuf DW 200 DUP (?,?)
- DSOX DW ?
- DSOY DW ?
- DSOZ DW ?
- DSOClr DB ?
-
- EVEN
- DrawSolid PROC
- mov esi,[SortedFacetsHeadPtr]
- or esi,esi
- jz _ret
- DSOML0: push esi
- mov edi,OFFSET DSOPBuf
- call ClearPBuf
- mov esi,[esp]
- mov esi,[esi+8] ; Get effective facet data ptr
- mov cx,[esi+6] ; Get # of points
- dec cx ; Loop for # of pts - 1
- mov al,BYTE PTR [esi+2] ; Get color
- mov [DSOClr],al
- add esi,8 ; Skip facet header
- mov ax,[esi]
- mov [DSOX],ax
- push ax
- mov ax,[esi+2]
- mov [DSOY],ax
- push ax
- mov ax,[esi+4]
- mov [DSOZ],ax
- push ax
- add esi,6 ; Skip 1st pt
- DSOML1: mov ax,[DSOX] ; Don't load again
- mov [A3DX1],ax
- mov ax,[DSOY]
- mov [A3DY1],ax
- mov ax,[DSOZ]
- mov [A3DZ1],ax
- mov ax,[esi]
- mov [A3DX2],ax
- mov [DSOX],ax
- mov ax,[esi+2]
- mov [A3DY2],ax
- mov [DSOY],ax
- mov ax,[esi+4]
- mov [A3DZ2],ax
- mov [DSOZ],ax
- mov edi,OFFSET DSOPBuf
- push esi
- push cx
- call Add3DLine
- pop cx
- pop esi
- add esi,6 ; Skip point
- dec cx
- jnz DSOML1
- ; Now, we gotta draw the last line
- pop [A3DZ2]
- pop [A3DY2]
- pop [A3DX2]
- mov ax,[DSOX]
- mov [A3DX1],ax
- mov ax,[DSOY]
- mov [A3DY1],ax
- mov ax,[DSOZ]
- mov [A3DZ1],ax
- mov edi,OFFSET DSOPBuf
- call Add3DLine
-
- ; Now dump the polygon to screen
- mov esi,OFFSET DSOPBuf
- mov al,[DSOClr]
- call DumpPBuf
-
- ; Now buffer the polygon for latter erasing
- mov esi,OFFSET DSOPBuf
- mov edi,[LinesBufferPtr]
- call AddPBuf
-
- ; Keep on with other polygons
- pop esi ; Restore ptr to the linked list
- mov esi,[esi]
- or esi,esi
- jnz DSOML0
- ret
- DrawSolid ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to draw the 2D projection of a 3D line
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- L3DX1 DW ?
- L3DY1 DW ?
- L3DZ1 DW ?
- L3DX2 DW ?
- L3DY2 DW ?
- L3DZ2 DW ?
- D3DLColor DB ?
- EVEN
- Draw3DLine PROC
- mov [D3DLColor],ah
- mov di,[L3DZ1] ; Get Z coor
- mov ax,[L3DX1] ; Get X coor
- imul [Dist]
- idiv di ; X' = X * Dist / Z
- add ax,160 ; To center in screen
- mov [X1],ax
- mov ax,[L3DY1] ; Get Y coor
- imul [Dist]
- idiv di ; Y' = Y * Dist / Z
- add ax,100
- mov [Y1],ax
- mov di,[L3DZ2] ; Get Z coor
- mov ax,[L3DX2] ; Get X coor
- imul [Dist]
- idiv di ; X' = X * Dist / Z
- add ax,160 ; To center in screen
- mov [X2],ax
- mov ax,[L3DY2] ; Get Y coor
- imul [Dist]
- idiv di ; Y' = Y * Dist / Z
- add ax,100
- mov [Y2],ax
- ; Clip the line in (X1,Y1)-(X2,Y2)
- call ClipLine
- jc D3DLL0 ; Completely invisible
- ; Buffer the line for later erasing:
- mov esi,[NumBufferedLinesPtr]
- movzx esi,WORD PTR [esi]
- shl esi,3 ; 8 bytes per buf. line
- add esi,[LinesBufferPtr]
- mov ax,[X1]
- mov [esi],ax
- mov ax,[Y1]
- mov [esi+2],ax
- mov ax,[X2]
- mov [esi+4],ax
- mov ax,[Y2]
- mov [esi+6],ax
- mov esi,[NumBufferedLinesPtr]
- inc WORD PTR [esi]
- ; Draw the line without clipping:
- mov ah,[D3DLColor]
- call DrawLine
- D3DLL0:
- ret
- Draw3DLine ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to add the 2D projection of a 3D line to a polygon buffer
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; EDI -> Polygon buffer
- EVEN
- A3DX1 DW ?
- A3DY1 DW ?
- A3DZ1 DW ?
- A3DX2 DW ?
- A3DY2 DW ?
- A3DZ2 DW ?
- A3DLPBuf DD ?
-
- EVEN
- Add3DLine PROC
- mov [A3DLPBuf],edi
- mov di,[A3DZ1] ; Get Z coor
- mov ax,[A3DX1] ; Get X coor
- imul [Dist]
- idiv di ; X' = X * Dist / Z
- add ax,160 ; To center in screen
- mov [ALPBX1],ax
- mov ax,[A3DY1] ; Get Y coor
- imul [Dist]
- idiv di ; Y' = Y * Dist / Z
- add ax,100
- mov [ALPBY1],ax
- mov di,[A3DZ2] ; Get Z coor
- mov ax,[A3DX2] ; Get X coor
- imul [Dist]
- idiv di ; X' = X * Dist / Z
- add ax,160 ; To center in screen
- mov [ALPBX2],ax
- mov ax,[A3DY2] ; Get Y coor
- imul [Dist]
- idiv di ; Y' = Y * Dist / Z
- add ax,100
- mov [ALPBY2],ax
- ; Clip the line in ALPB (X1,Y1)-(X2,Y2)
- call ClipVLine
- jc A3DLL0 ; Completely outside
- ; Add the line without further clipping:
- mov edi,[A3DLPBuf]
- call AddLineToPBuf
- A3DLL0:
- ret
- Add3DLine ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to build new facets clipping against Z = ZN
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- LastPoint DW ?
- VertCounter DW ?
-
- EVEN
- BuildClip PROC
- mov ebp,OFFSET ClippedFacetsBuffer
- mov esi,OFFSET Facets
- mov [NumFacets],0
- mov cx,NUM_FACETS
-
- ; Loops for all the facets in the scene
-
- BCML0: push cx ; Save facet counter
- mov edi,ebp
- movsw ; Copy facet type
- movsw ; Copy facet data lo
- movsw ; Copy facet data hi
- xor eax,eax
- stosw ; Initially 0 points in clipped facet
- lodsw ; Get # of points before clipping
- mov [VertCounter],ax
- mov ebx,eax
- add ebx,ebx ; # of bytes to the last point
- movzx ebx,WORD PTR [esi+ebx-2]
- mov [LastPoint],bx ; Keep inx of the last point
- mov eax,ebx ; \
- add ebx,ebx ; \
- add ebx,eax ; \
- add ebx,ebx ; ebx = 6 * inx
- mov dx,[ZN]
- xor cl,cl ; The flag
- cmp CameraPts[ebx+4],dx ; CMP Zlast,ZN
- jl BCML1
- inc cl
-
- ; Loops for all the vertices in the facet
-
- BCML1: movzx ebx,WORD PTR [esi]
- mov eax,ebx ; \
- add ebx,ebx ; \
- add ebx,eax ; \
- add ebx,ebx ; bx = 6 * inx
- add ebx,OFFSET CameraPts
- mov ax,[ebx+4]
- mov dx,[ZN]
- xor ch,ch
- cmp ax,dx
- jl BCL0
- inc ch
- BCL0: xor cl,ch
- jz BCL1 ; If both on the same side, needn't clip
- push cx
- push esi
- push ebp
- movzx esi,WORD PTR [LastPoint]
- mov ecx,esi ; \
- add esi,esi ; \
- add esi,ecx ; \
- add esi,esi ; si = 6 * inx
- add esi,OFFSET CameraPts
- mov cx,[ZN]
- sub cx,ax
- jns BCL2
- neg cx
- BCL2: sub ax,[esi+4]
- jns BCL3
- neg ax
- BCL3: mov bp,ax
- mov ax,[esi] ; Get X1
- sub ax,[ebx] ; AX = (X1-X0)
- imul cx ; AX = (ZN-Z0).(X1-X0)
- idiv bp ; AX = (ZN-Z0).(X1-X0)/(Z1-Z0)
- add ax,[ebx] ; AX += X0
- stosw
- mov ax,[esi+2] ; Get Y1
- sub ax,[ebx+2] ; AX = (Y1-Y0)
- imul cx ; AX = (ZN-Z0).(Y1-Y0)
- idiv bp ; AX = (ZN-Z0).(Y1-Y0)/(Z1-Z0)
- add ax,[ebx+2] ; AX += Y0
- stosw
- mov ax,[ZN]
- stosw
- pop ebp
- pop esi
- pop cx
- inc WORD PTR [ebp+6] ; One more point in clipped facet ptlist
- BCL1: mov cl,ch
- or cl,cl
- jz BCL4
- mov ax,[ebx]
- stosw
- mov ax,[ebx+2]
- stosw
- mov ax,[ebx+4]
- stosw
- inc WORD PTR [ebp+6] ; 1 more point ...
- BCL4: lodsw
- mov [LastPoint],ax
- dec [VertCounter]
- jnz BCML1
-
- cmp WORD PTR [ebp+6],0
- je BCL5
- mov ebp,edi
- inc [NumFacets]
- BCL5: pop cx
- dec cx
- jnz BCML0
-
- ret
-
- BuildClip ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to clear the screen (just 1st page)
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- ClrScr PROC
- mov dx,3C4h
- mov ax,0F02h ; Map Mask register = 1111b
- out dx,ax
- movzx edi,[VGASeg]
- shl edi,4
- sub edi,_code32a
- xor eax,eax ; Fill with zeros
- mov ecx,4096d ; Words in first page
- rep stosd
- ret
- ClrScr ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to clip the line defined by (X1,Y1)-(X2,Y2) to the 320x200 rect
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; We use the familiar Cohen-Sutherland algorithm:
- ;
- ; 1001 | 1000 | 1010
- ; ------------------
- ; 0001 | 0000 | 0010
- ; ------------------
- ; 0101 | 0100 | 0110
- ;
- EVEN
- ClipLine PROC
- ; In CL and CH we calc the codes for P1 and P2
- mov bx,[X1]
- mov bp,[X2]
- mov si,[Y1]
- mov di,[Y2]
- CLAgain:
- xor cl,cl ; Code for P1
- or bx,bx
- jns CL0
- or cl,0001b
- CL0: cmp bx,320
- jl CL1
- or cl,0010b
- CL1: or si,si
- jns CL2
- or cl,1000b
- CL2: cmp si,200
- jl CL3
- or cl,0100b
- CL3: xor ch,ch ; Code for P2
- or bp,bp
- jns CL4
- or ch,0001b
- CL4: cmp bp,320
- jl CL5
- or ch,0010b
- CL5: or di,di
- jns CL6
- or ch,1000b
- CL6: cmp di,200
- jl CL7
- or ch,0100b
- CL7:
- ; Now, we have: CL=P1 code, CH=P2 code, BX=X1, BP=X2, SI=Y1, DI=Y2
- mov al,cl
- or al,ch
- jnz CL8
- ; Both segments are inside the screen
- jmp CLExit
- CL8: test cl,ch
- jz CL9
- ; Both segments are outside on the same side
- stc ; Don't draw
- ret
- CL9: xor cl,ch
- cmp si,di ; Make sure Y1 < Y2
- jle CL10
- xchg si,di
- xchg bx,bp
- CL10:
- test cl,1000b ; Have to cut against Y=0 ?
- jz CL11
- ; Cut against Y=0
- push di
- sub bx,bp
- mov ax,bx
- imul di
- sub di,si
- idiv di
- add ax,bp ; NewX1 = X2+(X1-X2)*Y2/(Y2-Y1)
- mov bx,ax ; NewX1 = ^^^^^^^^^^^^^^^^^^^^^
- xor si,si ; NewY1 = 0
- pop di
- jmp CLAgain
- CL11: test cl,0100b
- jz CL12
- ; Cut against Y=199
- push si
- sub si,199
- sub di,199
- ; Cutting against 0
- sub bp,bx
- mov ax,bp
- imul si
- sub si,di
- idiv si
- add ax,bx ; NewX2 = X1+(X2-X1)*Y1/(Y1-Y2)
- mov bp,ax
- mov di,199 ; NewY2 = 199
- pop si ; NewY1 = OldY1
- jmp CLAgain
- CL12: cmp bx,bp ; Make sure X1 < X2
- jle CL15
- xchg si,di
- xchg bx,bp
- CL15: test cl,0001b ; Have to cut against X=0 ?
- jz CL13
- ; Cut against X=0
- push bp
- sub si,di
- mov ax,si
- imul bp
- sub bp,bx
- idiv bp
- add ax,di ; NewY1 = Y2+(Y1-Y2)*X2/(X2-X1)
- mov si,ax ; NewY1 = ^^^^^^^^^^^^^^^^^^^^^
- xor bx,bx ; NewX1 = 0
- pop bp
- jmp CLAgain
- CL13: test cl,0010b
- jz CLExit
- ; Cut against X=319
- push bx
- sub bx,319
- sub bp,319
- ; Cutting against 0
- sub di,si
- mov ax,di
- imul bx
- sub bx,bp
- idiv bx
- add ax,si ; NewY2 = Y1+(Y2-Y1)*X1/(X1-X2)
- mov di,ax
- mov bp,319 ; NewX2 = 319
- pop bx ; NewY1 = OldY1
- jmp CLAgain
- CLExit: ; We've passed all the clippings
- mov [X1],bx
- mov [X2],bp
- mov [Y1],si
- mov [Y2],di
- clc ; Visible
- ret
- ClipLine ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to clip line defined by ALPB (X1,Y1)-(X2,Y2) to the INFx200 rect
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; We use a variation of the familiar Cohen-Sutherland algorithm:
- ;
- ; 10
- ; ----
- ; 00
- ; ----
- ; 01
- ;
- EVEN
- ClipVLine PROC
- ; In CL and CH we calc the codes for P1 and P2
- mov bx,[ALPBX1]
- mov bp,[ALPBX2]
- mov si,[ALPBY1]
- mov di,[ALPBY2]
- CVLAgain:
- xor cl,cl ; Code for P1
- or si,si
- jns CVL2
- or cl,10b
- CVL2: cmp si,200
- jl CVL3
- or cl,01b
- CVL3: xor ch,ch ; Code for P2
- or di,di
- jns CVL6
- or ch,10b
- CVL6: cmp di,200
- jl CVL7
- or ch,01b
- CVL7:
- ; Now, we have: CL=P1 code, CH=P2 code, BX=X1, BP=X2, SI=Y1, DI=Y2
- mov al,cl
- or al,ch
- jnz CVL8
- ; Both segments are inside the rectangle
- jmp CVLExit
- CVL8: test cl,ch
- jz CVL9
- ; Both segments are outside on the same side
- stc ; Don't draw
- ret
- CVL9: xor cl,ch
- cmp si,di ; Make sure Y1 < Y2
- jle CVL10
- xchg si,di
- xchg bx,bp
- CVL10:
- test cl,10b ; Have to cut against Y=0 ?
- jz CVL11
- ; Cut against Y=0
- push di
- sub bx,bp
- mov ax,bx
- imul di
- sub di,si
- idiv di
- add ax,bp ; NewX1 = X2+(X1-X2)*Y2/(Y2-Y1)
- mov bx,ax ; NewX1 = ^^^^^^^^^^^^^^^^^^^^^
- xor si,si ; NewY1 = 0
- pop di
- jmp CVLAgain
- CVL11: test cl,01b
- jz CVLExit
- ; Cut against Y=199
- push si
- sub si,199
- sub di,199
- ; Cutting against 0
- sub bp,bx
- mov ax,bp
- imul si
- sub si,di
- idiv si
- add ax,bx ; NewX2 = X1+(X2-X1)*Y1/(Y1-Y2)
- mov bp,ax
- mov di,199 ; NewY2 = 199
- pop si ; NewY1 = OldY1
- jmp CVLAgain
- CVLExit: ; We've passed all the clippings
- mov [ALPBX1],bx
- mov [ALPBX2],bp
- mov [ALPBY1],si
- mov [ALPBY2],di
- clc ; Visible
- ret
- ClipVLine ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to sort the facets in back-to-front order for the painter's alg.
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- EVEN
- Averages DW ?,?,?
- CoorsCounter DW ?
- ThisFacetPtr DD ?
- NextFacetPtr DD ?
-
- EVEN
- SortByDist PROC
- mov [SortedFacetsHeadPtr],0
- mov esi,OFFSET ClippedFacetsBuffer
- mov cx,[NumFacets]
- or cx,cx
- jz SDExit
- mov [NextFreeSlotPtr],OFFSET SortedFacetsList
- mov [SortedFacetsHeadPtr],0
- SDML: push cx
- mov cx,[esi+6] ; Get # of pts in the facet
- mov [ThisFacetPtr],esi
- add esi,8 ; To point to the coors
- mov [CoorsCounter],6
- SDL0: push esi
- push cx ; Keep # of points
- xor dx,dx
- xor ax,ax
- SDL1: mov bx,[esi]
- or bx,bx
- jns SDL4
- neg bx
- sub ax,bx
- sbb dx,0
- add esi,6 ; To coor i of next point
- dec cx
- jnz SDL1
- jmp SDL5
- SDL4: add ax,bx
- adc dx,0
- add esi,6
- dec cx
- jnz SDL1
- SDL5: sub esi,4 ; When looping on coors Z, it will
- ; store the pointer to next facet0
- mov [NextFacetPtr],esi
- pop cx ; Restore # of points
- pop esi
- add esi,2 ; Switch to next coor
- idiv cx ; Calc average
- movzx ebx,WORD PTR [CoorsCounter]
- neg ebx
- add ebx,6
- mov Averages[ebx],ax
- sub [CoorsCounter],2
- jnz SDL0
- mov ax,[Averages] ; Get average X coor
- imul ax
- mov di,dx
- mov cx,ax
- mov ax,[Averages+2] ; Get average Y coor
- imul ax
- add cx,ax
- adc di,dx
- mov ax,[Averages+4] ; Get average Z coor
- imul ax
- add cx,ax
- adc di,dx
- ; Now we have x^2+y^2+z^2 in DI·CX, insert into the sorted list
- mov ebx,[NextFreeSlotPtr]
- mov [ebx+4],cx
- mov [ebx+6],di
- mov eax,[ThisFacetPtr]
- mov [ebx+8],ax
- ; Do the loop to insert
- mov ebx,OFFSET SortedFacetsHeadPtr
- SDL2: mov esi,[ebx] ; Get address of next facet item
- or esi,esi
- jz SDDoInsert
- cmp di,[esi+6] ; CMP ThisHiDist,ThatHiDist
- jg SDDoInsert
- jl SDGotoNext
- cmp cx,[esi+4]
- jge SDDoInsert
- SDGotoNext:
- mov ebx,esi
- jmp SDL2
- SDDoInsert:
- ; Here, bx points to the Next ptr to alter, [ebx] is the Next
- ; field to put in our Next field
- mov esi,[NextFreeSlotPtr]
- mov eax,[ebx]
- mov [esi],eax ; Set our Next field to insert
- mov [ebx],esi ; Alter the Next field
- add esi,12
- mov [NextFreeSlotPtr],esi ; Update NextFreeSlot
- ; Continue the loop
- mov esi,[NextFacetPtr]
- pop cx ; Restore # of facets
- dec cx
- jz SDExit
- jmp SDML
- SDExit:
- ret
- SortByDist ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to sequence the animation
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- TAGSIZE = 2 + 2*14 ; Tag id plus 14 words
- NextTag DD OFFSET Movement
- DSFramesLeft DW 0
- DSStart DW 6 DUP(?) ; Starting _ex,_ey,_ez,_ax,_ay,_az
- DSEnd DW 6 DUP(?) ; Ending "
- DSCrnt DW 6 DUP(?) ; Current value
- DSIntA DW 6 DUP(?) ; Integer advance (done always)
- DSFracA DW 6 DUP(?) ; Fractional advance (only when carry)
- DSFrac DW 6 DUP(?) ; Current fractional part
- DSAdjU DW 6 DUP(?) ; Adjust fractional part
- DSAdjD DW 6 DUP(?) ; Only when carry, substract this
-
- EVEN
- DoSeq PROC
- mov ax,[DSFramesLeft]
- or ax,ax
- jz DSInitTag
- jmp DSNrmSeq
- DSInitTag:
- ; So we have to setup the Bres data for the new sequence tag
- mov esi,[NextTag]
- add [NextTag],TAGSIZE
- mov ax,[esi]
- inc ax
- jnz DSL0
- mov [QuitPrg],1
- ret
- DSL0: ; So it's definitely a brand new animation tag
- inc esi
- inc esi
- mov edi,OFFSET DSStart
- mov cx,12
- rep movsw ; Get starting and ending coordinates
- lodsw ; Get the FOV
- mov [FOV],ax
- lodsw ; Get the # of frames for this tag
- mov [DSFramesLeft],ax
- cmp ax,1
- jne DSL4
- ; Needn't do a Bres 'cos it's just one frame
- mov esi,OFFSET DSStart
- mov edi,OFFSET DSCrnt
- mov cx,6
- rep movsw
- jmp DSTransfer
- DSL4: mov bp,ax ; Keep in BP the # of frames, during the MLoop
- mov esi,10 ; Start calculating from the last of the 6
- DSML0: mov bx,DSStart[esi]
- mov DSCrnt[esi],bx
- mov ax,DSEnd[esi]
- sub ax,bx ; AX is the total delta
- mov cx,1
- jns DSL2
- neg cx
- DSL2: mov DSFracA[esi],cx
- cwd
- idiv bp ; Divide by the # of frames
- mov DSIntA[esi],ax ; Integral advance
- or dx,dx
- jns DSL3
- neg dx
- DSL3: add dx,dx ; DX = 2 * dQuant
- mov DSAdjU[esi],dx
- mov ax,bp
- neg ax
- mov DSFrac[esi],ax
- mov ax,bp
- add ax,ax
- mov DSAdjD[esi],ax
- sub esi,1
- jc DSTransfer
- dec esi
- jmp DSML0
-
- DSNrmSeq: ; Advance the Bresenhams
- mov esi,10
- DSML1: mov ax,DSCrnt[esi]
- mov bx,DSFrac[esi]
- add ax,DSIntA[esi]
- add bx,DSAdjU[esi]
- jnc DSL1
- sub bx,DSAdjD[esi]
- add ax,DSFracA[esi]
- DSL1: mov DSCrnt[esi],ax
- mov DSFrac[esi],bx
- sub esi,1
- jc DSTransfer
- dec esi
- jmp DSML1
-
- DSTransfer: ; Transfer to _e and _a
- mov esi,OFFSET DSCrnt
- lodsw
- mov [_ex],ax
- lodsw
- mov [_ey],ax
- lodsw
- mov [_ez],ax
- lodsw
- mov [_ax],ax
- lodsw
- mov [_ay],ax
- lodsw
- mov [_az],ax
-
- dec [DSFramesLeft]
- ret
- DoSeq ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to clear a polygon buffer
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; IN: EDI -> Polygon buffer
- EVEN
- ClearPBuf PROC
- mov WORD PTR [edi],7FFFh ; Maximum X coor (32767)
- mov WORD PTR [edi+2],8000h ; Minimum X coor (-32768)
- mov esi,edi
- add edi,4
- mov cx,199
- rep movsd
- ret
- ClearPBuf ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to add one polygon buffer to another
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; IN: ESI -> Source polygon buffer (won't be changed)
- ; EDI -> Dest. polygon buffer (will be changed)
- EVEN
- AddPBuf PROC
- mov cx,200
- APBML: mov ax,[esi] ; Left X coor
- cmp ax,[edi]
- jg APBL0
- mov [edi],ax
- APBL0: mov ax,[esi+2]
- cmp ax,[edi+2]
- jl APBL1
- mov [edi+2],ax
- APBL1: add esi,4
- add edi,4
- dec cx
- jnz APBML
- ret
- AddPBuf ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to dump a polygon buffer
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; IN: ESI -> Polygon buffer
- ; AL : Color
- DPBClr DB ?
- DPBLeft DB 0Fh,0Eh,0Ch,08h
- DPBRight DB 00h,01h,03,07h
-
- EVEN
- DumpPBuf PROC
- mov [DPBClr],al ; Store color for latter use
- ; Init parameters for the 200 scans loop
- movzx edi,[VGASeg]
- shl edi,4
- sub edi,_code32a
- mov cx,200
- DPBML: push cx
- push edi
- push esi
- mov bx,[esi]
- cmp bx,319
- jg DPBL1 ; Don't draw, completely out-right
- mov cx,[esi+2]
- cmp cx,0
- jl DPBL1 ; Don't draw, completely out-left
- cmp bx,0
- jge DPBL2
- xor bx,bx
- mov [esi],bx
- DPBL2: cmp cx,319
- jle DPBL3
- mov cx,319
- mov [esi+2],cx
- DPBL3: ; Choose: Only one | Left & Right | Left & Middle & Right
- shr bx,2
- shr cx,2
- sub cx,bx
- jz DPBL5 ; Draw: both points in same 4pixel
- dec cx
- jz DPBL6 ; Draw: points in adjacent 4pixels
-
- ; Draw three parts
- movzx ebx,WORD PTR [esi]
- movzx ecx,WORD PTR [esi+2]
-
- ; Now draw left part
- mov ebp,ebx
- shr ebp,2
- add edi,ebp
- mov ebp,ebx
- and ebp,3
- mov ah,DPBLeft[ebp]
- mov al,2 ; Map mask register
- mov dx,3C4h
- out dx,ax ; Set this reg
- mov al,[DPBClr]
- stosb ; Draw and DI++
-
- ; Now draw middle part
- mov ax,0F02h
- out dx,ax ; Map mask reg: all planes
- mov ebp,ecx
- and bl,0FCh
- sub ebp,ebx
- shr ebp,2
- dec ebp
- xchg ecx,ebp
- mov ebx,ecx
- shr ecx,1
- mov al,[DPBClr]
- or ecx,ecx
- jz DPBL7
- mov ah,al
- rep stosw ; Draw middle 2*(n%2) 4pixels
- DPBL7: and bl,1
- jz DPBL4
- stosb ; Draw last 4pixel if necessary
- DPBL4:
- ; Now draw right part
- and ebp,3
- mov ah,DPBRight[ebp]
- mov al,2
- out dx,ax
- mov al,[DPBClr]
- stosb
- jmp DPBL1
-
- DPBL5: ; Draw if both points are in the same 4pixel
- movzx ebx,WORD PTR [esi]
- mov ebp,ebx
- shr ebp,2
- add edi,ebp
- and ebx,3
- mov ah,DPBLeft[ebx]
- movzx ebx,WORD PTR [esi+2]
- and ebx,3
- and ah,DPBRight[ebx]
- mov al,2
- mov dx,3C4h
- out dx,ax
- mov al,[DPBClr]
- stosb
- jmp DPBL1
-
- DPBL6: ; Draw if both points are in adjacent 4pixels
- movzx ebx,WORD PTR [esi]
- mov ebp,ebx
- shr ebp,2
- add edi,ebp
- and ebx,3
- mov ah,DPBLeft[ebx]
- mov al,2
- mov dx,3C4h
- out dx,ax
- mov al,[DPBClr]
- stosb
- movzx ebx,WORD PTR [esi+2]
- and ebx,3
- mov ah,DPBRight[ebx]
- mov al,2
- out dx,ax
- mov al,[DPBClr]
- stosb
- ;jmp DPBL1
-
-
- ; Keep on with the loop
- DPBL1: pop esi
- pop edi
- pop cx
- add edi,80d
- add esi,4
- dec cx
- jnz DPBML
- ret
- DumpPBuf ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Function to insert a line into a polygon buffer
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; IN: EDI -> Polygon buffer
- ;
- EVEN
- ALPBX1 DW ?
- ALPBY1 DW ?
- ALPBX2 DW ?
- ALPBY2 DW ?
-
- DD ?
- ALPBAdjFrac DD 0
-
- DD 1
- ALPBAdjCoorX DD 0
-
- EVEN
- AddLineToPBuf PROC
- movzx eax,WORD PTR [ALPBY2]
- movzx ebx,WORD PTR [ALPBY1]
- cmp eax,ebx
- je _ret
- ja ALPBL1 ; Y2 > Y1 => don't swap
- mov [ALPBY1],ax
- mov [ALPBY2],bx
- xchg eax,ebx
- movzx ecx,WORD PTR [ALPBX1]
- movzx edx,WORD PTR [ALPBX2]
- mov [ALPBX1],dx
- mov [ALPBX2],cx
- ALPBL1: sub eax,ebx
- mov ebp,eax ; EBP = dY
- shl ebx,2
- add edi,ebx
- mov ecx,eax
- inc ecx ; ECX = dY + 1
- mov ax,[ALPBX2]
- sub ax,[ALPBX1] ; AX = dX
- movsx eax,ax
- jns ALPBL4 ; Going from left to right
- neg eax ; Make dX >= 0
- mov [ALPBAdjCoorX-4],-1 ; Coor adjusts negative
- ALPBL4:
- cdq
- idiv ebp ; EAX = dX / dY
- mov esi,edx ; ESI = dX % dY
- mov edx,eax ; EDX = dX / dY
- neg ebp ; EBP = - dY
- mov eax,ebp
- add eax,eax ; EAX = - 2 * dY
- mov [ALPBAdjFrac-4],eax
- movzx eax,[ALPBX1] ; EAX = X1
- add esi,esi ; ESI = 2 * (dX % dY)
- cmp DWORD PTR [ALPBAdjCoorX-4],1
- je ALPBML
- neg edx
- ALPBML: cmp ax,[edi]
- jg ALPBL2 ; Don't adjust left X
- mov [edi],ax
- ALPBL2: cmp ax,[edi+2]
- jl ALPBL3
- mov [edi+2],ax
- ALPBL3: add edi,4
- add eax,edx ; Increment X always
- add ebp,esi ; Increment fractional part
- sbb ebx,ebx
- shl ebx,2
- add eax,ALPBAdjCoorX[ebx] ; Adjust Coor X (1 or 0)
- add ebp,ALPBAdjFrac[ebx] ; Adjust fractional part (0 or -2.dY)
- dec ecx
- jnz ALPBML
- mov [ALPBAdjCoorX-4],1
- ret
- AddLineToPBuf ENDP
-
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- ; Main function
- ; ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- I = 0
- prueba label word
- REPT 200
- DW 0, 0
- ENDM
-
- _main:
- sti
- Main PROC
- mov v86r_ax,0013h
- mov al,10h
- int 33h ; Standard 320x200x256 vmode
- mov dx,3C4h
- mov al,04
- out dx,al
- inc dx
- in al,dx ; Read Sequencer memory mode
- and al,NOT 8 ; register and unCHAIN4
- out dx,al
-
- mov dx,3C4h
- mov ax,0F02h ; Map Mask register = 1111b
- out dx,ax
- mov edi,0A0000h
- sub edi,_code32a
- xor eax,eax ; Fill with zeros
- mov ecx,16384d ; Dwords in each map
- rep stosd
-
- mov dx,3D4h
- mov al,14h
- out dx,al
- inc dx
- in al,dx
- and al,NOT 64 ; Turn off DWORD mode
- out dx,al
-
- mov dx,3D4h
- mov al,17h
- out dx,al
- inc dx
- in al,dx
- or al,64 ; Turn on BYTE mode
- out dx,al
-
- cmp [Mode],WIREFRAME
- jnz ML4
- mov [LinesBufferPtr],OFFSET LinesBuffer1
- mov [NumBufferedLinesPtr],OFFSET NumBufferedLines1
- mov [NumBufferedLines1],0
- mov [NumBufferedLines2],0
- jmp ML5
- ML4: mov [LinesBufferPtr],OFFSET LinesBuffer1
- mov edi,OFFSET LinesBuffer1
- call ClearPBuf
- mov edi,OFFSET LinesBuffer2
- call ClearPBuf
- ML5:
- mov [QuitPrg],0
- mov [ZN],128
- MMainLoop:
- SetBorder 2
- call DoSeq
- SetBorder 3
- call CalcM
- SetBorder 4
- call CalcDist
- SetBorder 5
- call WToCam
- SetBorder 6
- call BuildClip
- SetBorder 7
- call SortByDist
- SetBorder 8
- cmp [Mode],WIREFRAME
- jnz ML0
- call DrawWire
- jmp ML1
- ML0: call DrawSolid
- ML1:
- SetBorder 0
-
- mov dx,3DAh
- MWaitA: in al,dx
- test al,8
- jnz MWaitA
-
- mov ax,[VGASeg] ; Show just-drawn page
- mov cl,4
- shl ax,cl
- mov al,0Ch ; Start Address Hi register
- mov dx,3D4h
- out dx,ax
-
- mov dx,3DAh
- MWait0: in al,dx
- test al,8
- jz MWait0
-
- mov dx,3DAh
- MWait1: in al,dx
- test al,8
- jnz MWait1
-
- SetBorder 1
-
- mov eax,[LinesBufferPtr]
- xor eax,OFFSET LinesBuffer1
- xor eax,OFFSET LinesBuffer2
- mov [LinesBufferPtr],eax
- mov eax,[NumBufferedLinesPtr]
- xor eax,OFFSET NumBufferedLines1
- xor eax,OFFSET NumBufferedLines2
- mov [NumBufferedLinesPtr],eax
- xor [VGASeg],400h
- cmp [Mode],WIREFRAME
- jnz ML2
- call EraseBufferedLines
- jmp ML3
- ML2: call EraseBufferedPolys
- ML3:
-
- mov ax,[QuitPrg]
- or ax,ax
- jnz MExit
- jmp MMainLoop
-
- MExit: mov v86r_ax,0003
- mov al,10h
- int 33h
- mov edx,OFFSET ByeMsg
- add edx,_code32a
- mov ebx,edx
- and dx,0Fh
- mov v86r_dx,dx
- shr ebx,4
- mov v86r_ds,bx
- mov v86r_ah,9
- mov al,21h
- int 33h
- jmp _exit
- Main ENDP
-
- code32 ends
-
- END
-